//
// Created by none98 on 2021/9/14.
//

#include <spdlog/spdlog.h>
#include "TimerEventQueue.h"
#include "Timer.h"

std::vector<TimerCallBack> TimerEventQueue::GetExpiredEvents(const TimeStamp &expire) {
    std::unique_lock<std::mutex> lock(objectMutex);
    std::vector<TimerCallBack> vec;
    std::vector<std::pair<Timer,long>> timerVec;
    auto index = timerMap.begin();
    while(index!=timerMap.end() and index->first.GetExpire()<expire){
        //index->first.callBack();
        vec.push_back(index->first.callBack);
        if(index->first.IsCircular()){
            Timer timer = index->first;
            timer.SetExpire(timer.GetExpire()+timer.GetInterval());
            timerVec.push_back(std::pair<Timer,long>(timer,index->second));
        }
        index = timerMap.erase(index);
    }
    for(auto i : timerVec)
        timerMap.insert(i);
    return std::move(vec);
}

long TimerEventQueue::AddTimer(const Timer &timer) {
    std::unique_lock<std::mutex> lock(objectMutex);
    timerMap.insert(std::pair<Timer,long>(timer,sequence++));
    return sequence-1;
}

void TimerEventQueue::CancelTimerByFd(int fd) {
    std::unique_lock<std::mutex> lock(objectMutex);
    auto index = timerMap.begin();
    while(index!=timerMap.end()){
        if(index->first.GetFdOfTimer()==fd){
            index=timerMap.erase(index);
        }else
            index++;
    }
}

void TimerEventQueue::CancelTimerBySequence(long seq) {
    std::unique_lock<std::mutex> lock(objectMutex);
    auto index = timerMap.begin();
    while(index!=timerMap.end()){
        if(index->second==seq){
            index = timerMap.erase(index);
        }else
            index++;
    }
}
